=Event system=
We are using rabbitmq to publish/subscribe the events happenned in the system. For every kind of event, there are two defined methods .
# on change event: the event information is published whenever the state is changed for the system. 
# on request sync: the complete event information is published whenever system is receiving sync commands.
Notice: in order to simplify the design, the event information published by on_change_event or on_request_sync are using the same object format except there is a flag(is_sync) to distinguish them. And also, they are sending though the same exchange.

== online/offline ==
* Event exchange type: '''topic'''
* Event exchange name: '''voice_events'''
* Event routing key: '''terminal.online_offline_states'''
* sync listening exchange type: '''fanout'''
* sync listening exchange name: '''voice_sync_online'''
* sync routing key: empty
* sync msg: '''sync_terminal_states'''
===sample===
* format: yaml
* sample:
<pre>
---
is_sync: false
online:
- f4908713
- '00000030'
- 00000018
- 00000089
- 00000038
- 00000028
- '00000020'
- 00000078
- '00000004'
- f5084724
- '00000006'
- f8603151
- '00000024'
- '00000022'
- f7475634
- a1cc94a6
- f5601645
- '00000007'
- '00000075'
online_dialno:
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- ''
- '1003'
- ''
- ''
- ''
offline: []
offline_dialno: []
</pre>
<pre>
---
is_sync: true
online:
- f4908713
- '00000030'
- 00000018
- 00000089
- 00000038
- 00000028
- '00000020'
- 00000078
- '00000004'
- f5084724
- '00000006'
- f8603151
- '00000024'
- '00000022'
- f7475634
- a1cc94a6
- f5601645
- '00000007'
- '00000075'
- '00000014'
- 00000019
- f2494470
- '00000034'
- 00000086
- '00000005'
- '00000015'
- '00000003'
- 00000087
- '00000032'
- f0431540
offline: []

</pre>

===explain===
* online section: defines all the terminals which are currently online.
* online_dialno section: one to one map to online section, which defines the dialno for each sn. '''Notice:'''Only valid in not sync state.
* offline section: defines all the terminals which are currently offline.
* offline_dialno section: one to one map to offline section, which defines the dialno for each sn. '''Notice:'''Only valid in not sync state.
Notice: 
# In non-sync mode, online/offline defines which terminal's states are changed.
# In sync mode, online list defines all terminals which are on line. And if terminal is not in the online list, it is assumed to be offline.

== Channel states ==
* Event exchange type: '''topic'''
* Event exchange name: '''voice_events'''
* Event routing key: '''channel.call_state'''
* sync listening exchange type: '''fanout'''
* sync exchange name: '''voice_sync_events'''
* sync routing key: empty
* sync msg: '''channel.call_state'''
* terminal startup msg: '''terminal.voice_crash'''  it will do full sync including clean current active sessions
** terminal startup msg arguments: [dialno]
* terminal reboot msg:  '''terminal.reboot'''   the machine is reboot or startup from power without active calls
** terminal reboot msg argumetns: [dialno]
* terminal reboot msg:  '''terminal.reboot_calls''' the machine is reboot or startup from power with active calls
* cluster states sync msg: 
** '''cluster.master''': we become master
** '''cluster.backup''': we become backup server
===sample===
* format: yaml
* sample:
<pre>
--- !ruby/object:Channel_states
is_sync: false
evts: 
  - uuid: 65da6180-877b-4378-a0bc-161f969fe643
    s_id: 599067108406308
    t_id: 0008
    c_type: broadcast
    is_caller: ''
    j_name: broadcast
    t_type: gui
    t_src: client
    r_uuid: ''
    from: '0008'
    to: ''
    des: '*#BROADCAST#_#SPE#_6c851bb_?#*#b_n=6c851bb;d_ds=1004:1003:1002 '
    state: EARLY
    is_loopback: false
  - uuid: 65da6180-877b-4378-a0bc-161f969fe643
    s_id: 599067108406308
    t_id: 0008
    c_type: broadcast
    is_caller: ''
    j_name: broadcast
    t_type: gui
    t_src: client
    r_uuid: ''
    from: '0008'
    to: ''
    des: '*#BROADCAST#_#SPE#_6c851bb_?#*#b_n=6c851bb;d_ds=1004:1003:1002 '
    state: RINGING
    is_loopback: false
  - uuid: 65da6180-877b-4378-a0bc-161f969fe643
    s_id: 599067108406308
    t_id: 0008
    c_type: broadcast
    is_caller: ''
    j_name: broadcast
    t_type: gui
    t_src: client
    r_uuid: ''
    from: '0008'
    to: ''
    des: '*#BROADCAST#_#SPE#_6c851bb_?#*#b_n=6c851bb;d_ds=1004:1003:1002 '
    state: EARLY
    is_loopback: false
  - uuid: 65da6180-877b-4378-a0bc-161f969fe643
    s_id: 599067108406308
    t_id: 0008
    c_type: broadcast
    is_caller: true
    j_name: broadcast
    t_type: gui
    t_src: client
    r_uuid: ''
    from: '0008'
    to: ''
    des: '*#BROADCAST#_#SPE#_6c851bb_?#*#b_n=6c851bb;d_ds=1004:1003:1002 '
    state: ACTIVE
    is_loopback: false

</pre>

===explain===
For each call, it consists a list of channels. Each channel can be imaged as a connection to a terminal. Notice: we are using loopback channel as well, which is hacking way to handle some conditions in the system. Normally, we could ignore them.<br/>
Therefore, we could use each channel's state to update terminal state.
* uuid: can be used to kill this channel
* s_id: sequence id, can be used to kill this call
* t_id: current terminal id
* c_type: conversion type
* is_caller: defines as if this terminal is the caller.
* j_name: job name
* t_type: trigger type
* t_src: trigger source
* r_uuid: reference uuid, which is the schedule uuid and job uuid
* from: who dial it
* to: target id. Notice: it may be empty
* des: the dialno
* state: the current call states. valid values are: DOWN/DIALING/RINGING/EARLY/ACTIVE/HELD/HANGUP/UNHOLD
** HELD: means pause
** ACTIVE: means stream running
** DIALING/RINGING/EARLY: states before ACTIVE.
** HANGUP/DOWN: call is ended
** UNHOLD: not very sure.
* is_loopback: true/false. normally, we could ignore this channel, as it is handled as system internal loopback.
'''Notice:'''Some attributes may be missing in some states.

==Dialno event==
Whenever a new terminal is added to system or existed terminal's dialno has been changed, we will publish event to rabbitmq to sync the states.
* Event exchange type: topic
* Event exchange name: voice_events
* Event routing key: terminal.dialno
* sync listening exchange type: fanout
* sync listening exchange name: voice_sync_terminal
* sync routing key: empty
* sync msg: sync_dialno_states

=== sample ===
* format: yaml
* sample:
<pre>
---
is_sync: false
terminals:
- !ruby/object:Terminal::TerminalDialno
  t_sn: '00000001'
  dialno: '1006'
</pre>
<pre>
---
is_sync: true
terminals:
- !ruby/object:TerminalDialno
  t_sn: f8611510
  dialno: '1000'
- !ruby/object:TerminalDialno
  t_sn: f6482105
  dialno: '1005'
- !ruby/object:TerminalDialno
  t_sn: f5944661
  dialno: '1002'
- !ruby/object:TerminalDialno
  t_sn: f8613240
  dialno: '1001'
- !ruby/object:TerminalDialno
  t_sn: 8d1cfb56
  dialno: '1004'
- !ruby/object:TerminalDialno
  t_sn: '00000001'
  dialno: '1006'
- !ruby/object:TerminalDialno
  t_sn: a1cc94a6
  dialno: '1003'

</pre>